package mytest

import (
	"fmt"
	"math"
)

//无参函数
func printstring() {
	fmt.Println("hello jonson")
}

//带参函数
func add(a, b int) {
	fmt.Println("a+b=", a+b)
}

//返回值
func addres(a, b int) int {
	return a + b
}

// 有名字的返回值
func addresname(a, b int) (sum int) {
	sum = a + b
	return
}

//多返回值
func addmuti(a, b int) (int, int) {
	add := a + b
	mul := a * b

	return add, mul
}

//不定个数参数
func addsum(nums ...int) int {
	var sum int
	for _, value := range nums {
		sum += value
	}
	return sum
}

//闭包
func greetjonson() {
	x := 0

	increment := func() int {
		x++
		return x
	}

	fmt.Println(increment())
	fmt.Println(increment())
}

//函数作为返回值
func makeGreeter() func() string {

	return func() string {
		return "hello jonson"
	}
}

//闭包与函数返回值
func makeEvenGenerator() func() int {
	i := 0
	return func() int {
		i += 2
		return i
	}
}

//callback函数作为参数
func visit(numbers []int, callback func(int)) {

	for _, n := range numbers {
		callback(n)
	}
}

//递归

//  计算阶乘     5   5*4*3*2*1
func factorial(x uint) uint {

	if x == 0 {
		return 1
	}
	return x * factorial(x-1)
}

//fabicc
func fabicc(x uint) uint {

	if x == 0 {
		return 0
	}
	if x == 1 {
		return 1
	}

	return fabicc(x-2) + fabicc(x-1)
}

func TestFunc() {

	printstring()
	add(2, 4)

	fmt.Println("addres 6+7 = ", addres(6, 7))
	fmt.Println("addresname 3+4 = ", addresname(3, 4))

	add, sum := addmuti(5, 6)
	fmt.Printf("addmuti 5+6=%d,5*6=%d\n", add, sum)

	ADDsum := addsum(1, 2, 3, 4, 5)
	fmt.Println("addsum = ", ADDsum)

	//无参匿名函数
	func() {
		fmt.Println("jonson")
	}()

	//有参匿名函数
	func(data int) {
		fmt.Println("data:", data)
	}(5)

	//有返回值的匿名函数
	result := func(data float64) float64 {
		return math.Sqrt(data)
	}(9)

	fmt.Println("result:", result)

	greet := func() {
		fmt.Println("greet jonson")
	}
	greet()

	fmt.Printf("greet的类型是%T\n", greet)

	//闭包
	greetjonson()

	//函数作为返回值

	makejonson := makeGreeter()

	fmt.Printf("类型：%T，返回值：%v\n", makejonson, makejonson())

	//闭包做为返回值
	makeeven := makeEvenGenerator()

	fmt.Println("makeeven i = ", makeeven())
	fmt.Println("makeeven i = ", makeeven())
	fmt.Println("makeeven i = ", makeeven())

	//callback函数作为参数
	visit([]int{1, 2, 3, 4}, func(n int) {
		fmt.Println(n + 1)
	})

	//死循环
	fmt.Println(factorial(5))

	var i uint = 0
	for ; i < 20; i++ {

		fmt.Println(fabicc(i))

	}
}
